using System;
using System.Threading;
using System.Runtime.InteropServices;

namespace MusicPlayer
{

	[ComVisible(false)]
	public class SecureTimer : IDisposable
	{
		private int interval;
		private Timer timer;
		private TimerCallback timerDelegate;
		private bool disposed;

		public event EventHandler Tick;

		public SecureTimer()
		{
			this.disposed = false;
			this.timer = null;
			this.interval = 50;
			this.timerDelegate = null;
			this.timerDelegate = new TimerCallback(this.timer_Tick);
		}

		public SecureTimer(int interval)
		{
			this.disposed = false;
			this.timer = null;
			this.interval = 50;
			this.timerDelegate = null;
			this.interval = interval;
			this.timerDelegate = new TimerCallback(this.timer_Tick);
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		private void Dispose(bool disposing)
		{
			if (!this.disposed)
			{
				try
				{
					this.Stop();
				}
				catch
				{
				}
			}
			this.disposed = true;
		}

		~SecureTimer()
		{
			this.Dispose(false);
		}

		private void InvokeDelegate(Delegate del, object[] args)
		{
			System.ComponentModel.ISynchronizeInvoke target = del.Target as System.ComponentModel.ISynchronizeInvoke;
			if (target != null)
			{
				if (!target.InvokeRequired)
				{
					del.DynamicInvoke(args);
				}
				else
				{
					try
					{
						target.BeginInvoke(del, args);
					}
					catch
					{
					}
				}
			}
			else
			{
				del.DynamicInvoke(args);
			}
		}

		private void ProcessDelegate(Delegate del, params object[] args)
		{
			if ((del != null) && (this.timer != null))
			{
				lock (this.timer)
				{
					foreach (Delegate delegate2 in del.GetInvocationList())
					{
						this.InvokeDelegate(delegate2, args);
					}
				}
			}
		}

		public void Start()
		{
			if (this.timer == null)
			{
				this.timer = new Timer(this.timerDelegate, null, this.interval, this.interval);
			}
		}

		public void Stop()
		{
			if (this.timer != null)
			{
				lock (this.timer)
				{
					this.timer.Change(-1, -1);
					this.timer.Dispose();
					this.timer = null;
				}
			}
		}

		private void timer_Tick(object state)
		{
			if (this.Tick != null)
			{
				this.ProcessDelegate(this.Tick, new object[] { this, EventArgs.Empty });
			}
		}

		// Properties
		public bool Enabled
		{
			get
			{
				return (this.timer != null);
			}
			set
			{
				if (value)
				{
					this.Start();
				}
				else
				{
					this.Stop();
				}
			}
		}

		public int Interval
		{
			get
			{
				return this.interval;
			}
			set
			{
				if (value <= 0)
				{
					this.interval = -1;
				}
				else
				{
					this.interval = value;
				}
				if (this.timer != null)
				{
					this.timer.Change(this.interval, this.interval);
				}
			}
		}
	}

}
